#pragma once
#include "ComHeader.h"
#include "BezierSolid.h"
#include "Intersection.hpp"
#include "Ray.hpp"
#include "Bounds3.hpp"

class BezierCell;
struct BVHBuildNode;
// BVHAccel Forward Declarations
struct BVHPrimitiveInfo;



class BVHAccel {

public:
    // BVHAccel Public Types
    enum class SplitMethod { NAIVE, SAH };

    // BVHAccel Public Methods
    BVHAccel() {
        maxPrimsInNode = 1;
        splitMethod = SplitMethod::NAIVE;
        primitives.clear();
    }
    BVHAccel(std::vector<BezierCell> p, int maxPrimsInNode = 1, SplitMethod splitMethod = SplitMethod::NAIVE);
    ~BVHAccel() {}

    //Intersection Intersect(const Ray &ray,Vector3f param) const;
    void getIntersectCells(const Ray& ray, std::vector<BezierCell*>& cells);
    //Intersection getIntersection(BVHBuildNode* node, const Ray& ray, Vector3f param)const;
    void getIntersection1(BVHBuildNode* node, const Ray& ray, std::vector<BezierCell*>& cells);
    BVHBuildNode* root;

    // BVHAccel Private Methods
    BVHBuildNode* recursiveBuild(std::vector<BezierCell*>objects);

    // BVHAccel Private Data
    int maxPrimsInNode;
    SplitMethod splitMethod;
    std::vector<BezierCell> primitives_cell;
    std::vector<BezierCell*> primitives;
};

struct BVHBuildNode {
    Bounds3 bounds;
    BVHBuildNode *left;
    BVHBuildNode *right;
    BezierCell* object;

public:
    int splitAxis=0, firstPrimOffset=0, nPrimitives=0;
    // BVHBuildNode Public Methods
    BVHBuildNode(){
        bounds = Bounds3();
        left = nullptr;right = nullptr;
        object = nullptr;
    }
};
